<?php

use Illuminate\Contracts\Console\Kernel;
use WeForge\Runtime\CliHandlerFactory;
use WeForge\Runtime\Container;
use WeForge\Runtime\Fpm\Fpm;
use WeForge\Runtime\Fpm\FpmRequest;
use WeForge\Runtime\StorageDirectories;

ini_set('display_errors', '1');

error_reporting(E_ALL);

if (! file_exists('/tmp/opcache')) {
    mkdir('/tmp/opcache');
}

require __DIR__.'/vendor/autoload.php';

/*
|--------------------------------------------------------------------------
| Cache Configuration
|--------------------------------------------------------------------------
|
| To give the application a speed boost, we are going to cache all of the
| configuration files into a single file. The file will be loaded once
| by the runtime then it will read the configuration values from it.
|
*/

with(require __DIR__.'/bootstrap/app.php', function ($app) {
    StorageDirectories::create();

    $app->useStoragePath(StorageDirectories::path());

    fwrite(STDERR, "Caching Laravel Configuration\n");

    $app->make(Kernel::class)->call('config:cache');
});

/*
|--------------------------------------------------------------------------
| Listen For CLI Invocations
|--------------------------------------------------------------------------
|
| When receiving CLI requests to the CLI environment, we simply send
| them to the appropriate handlers based on if they are CLI commands
| or queued jobs. Then we'll return a response back to the user.
|
*/

if (isset($_ENV['APP_RUNNING_IN_CONSOLE']) && $_ENV['APP_RUNNING_IN_CONSOLE'] === 'true') {
    return Container::handleInvocation(function ($request) {
        return CliHandlerFactory::make($request)
                                ->handle($request);
    });
}

/*
|--------------------------------------------------------------------------
| Listen For HTTP Invocations
|--------------------------------------------------------------------------
|
| When using FPM, we will listen for HTTP invocations and proxy them
| through the FPM process. We'll then return formatted FPM response
| back to the user. We'll monitor FPM to make sure it is running.
|
*/

try {
    $fpm = Fpm::boot();

    Container::handleInvocation(function ($request) use ($fpm) {
        $fpm->ensureRunning();

        return $fpm->handle(
            FpmRequest::createFromRequest($request)
                            ->withScriptFilename(__DIR__.'/httpHandler.php')
        );
    });
} catch (Throwable $error) {
    Container::handleInvocation(function () use ($error) {
        return Fpm::handleException($error);
    });
}
